#pragma once
#include "components.h"
#include "Eigen/Dense"
#include "outmgr.h"
#include <fstream>
#include <sstream>
#include "ThreadPool.h"
#include <map>
#include "param.h"
#include "electric_bases.h"
#include "stdarg.h"

class EMT_component : public electric_base // 一个假定的元件，方便进行计算用
{
public:
    int num_node;
    int num_br;

    map<string, electric_base *> clist;
    void add_comp(electric_base *c, ...)
    {
        va_list args;
        va_start(args, c);
        string name = c->name;
        while (c != NULL)
        {
            c = va_arg(args, electric_base *);
            name = c->name;
            if (c == NULL)
                break;
            if (name == "")
            {
                cout << "error: clist is adding a no name component!" << endl;
                exit(-1);
            }
            clist[c->name] = c;
        }
    }

    MatrixXd Y, V, V_last_iteration, J;
    MatrixXd A, Yg;
    vector<double> iter_err; 

    electric_base *get_comp(string name)
    {
        string comp_name, id;
        // 分割name字符串，分隔符为下划线“_”，其第一个字符串存储于comp_name中，第二个字符串存储于id中
        int index = name.find("_");
        comp_name = name.substr(0, index);
        // id = name.substr(index + 1, name.length() - index - 1);
        id = name.substr(index + 1);
        int index = stod(id);
        auto result = clist.find(comp_name);
        if (clist.find(comp_name) != clist.end())
        {
            return result->second + index;
        }
        return nullptr;
    }

    // 器件开始
    DAB dab;
    single_phase_voltage_source vsource;
    resistor rload,rGND1,rGND2;
    // 器件结束

    EMT_component()
    {
        name = "EMT_MAIN";
    }
    void control(double simulation_time);
    void begin(param &Params);
    void dsdyn_out_iteration(double delt = 0, double simulation_time = 0.0);
    void dsdyn_in_iteration(double delt = 0, double simulation_time = 0.0);
    void dsout_out_iteration();
    void dsout_in_iteration();
    void G_Ihis_mapping();
    void get_num_node() { num_node = brs.get_num_node(); }
    void get_num_br() { num_br = brs.get_num_br(); }
};

class EMT
{
public:
    bool if_iteration = true;
    double simulation_time = 0.0;
    double delt = 1e-8;
    int breaktype = 0;
    int iteration_count = 0;
    const int iteration_max = 10;
    const double eps = 1.0e-6;
    double end_time = 0.2;

    EMT_component ec;
    string model_path;
    // 器件相关的内容
    // 器件挪到EC中去管理了
    ///////////////////器件内容结束
    void begin();
    void control();
    void dsdyn_out_iteration();
    void dsdyn_in_iteration();
    void emtdc();
    void dsout_in_iteration();
    void dsout_out_iteration();
    void solve();
    bool timezero() { return (simulation_time < delt); }
    param load(string path);

    double my_max(vector<double> &data);
    outmgr omgr;
    ofstream fout;

    ThreadPool *pool; // 并行计算的pool
    condition_variable cv;
    mutex mtx;

    // below two are in other threads
    static void bar_print(bool *is_simulation_end, double *end_time, double *simulation_time);
    void file_print();
};
